#!/usr/bin/python

#this python script reads the file "./probe" which contains the response from a tracker. the "probe" file is created by the python script 
#trackerProbe.py. This script connects to every peer listed assuming there are 10 peers in the response. It also requests piece 10 block 0
import string
import socket
import sys
import signal
import time
import socket
from threading import Thread

class Test(Thread):
    """This thread connects to a peer, and prints everything they send. 
    If the characters they send are not in string.letters, it prints the
    decimal value instead."""
    def __init__ (self,ip,port):
      Thread.__init__(self)
      self.ip = ip
      self.port = port
      self.responses = []
    def run(self):
        ip = self.ip
        port = self.port
        responses = self.responses
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#        print "got ip: {0} and port: {1}".format(ip,port)
        hash = "C8 63 65 9D 10 5E 9C 93 E9 4C 59 23 82 F5 2B 60 CE DB 05 44"
        peerid = "A0 70 00 00 00 00 00 00 07 77 A0 70 00 00 00 00 00 00 07 77"
        hash = hash.split(" ");
        peerid = peerid.split(" ");
        for i in range(20):
            hash[i] = chr(int(hash[i],16))
            peerid[i] = chr(int(peerid[i],16))            
        mesg = chr(19)+"BitTorrent protocol\0\0\0\0\0"+chr(0)+chr(0)+chr(0);
        for i in hash:
            mesg+=i;
        for i in peerid:
            mesg+=i;
#        for c in mesg:
#            if not c in string.letters:
#                print ord(c),
#            else:
#                print c,
        try:
            s.connect((ip,int(port)))
        except socket.error, msg:
            s.close()
            s = None
        if s is None:
            print "couldn't connect:\t {0}:{1}".format(ip,port)
            return;
        else:
            print "connected to:\t\t {0}:{1}".format(ip,port)
        print "sending: {0}:{1}  ".format(ip,port), mesg
        s.send(mesg)
        recvlen = 0
        while recvlen<68+181:
            data = s.recv(4096);
            recvlen +=len(data)
            if not data:    
                print "disconnect:\t\t {0}:{1} ".format(ip,port)
                sys.exit(1);
            print "recv {0} :\t\t {1}:{2} ".format(len(data),ip,port),
            for c in data:
                if not c in string.letters:
                    print "{0}".format(ord(c)),
                else:
                    print c,
            print ""
            responses.append(data)
        s.send("\0\0\0"+chr(1)+chr(1))
        s.send("\0\0\0"+chr(1)+chr(2))
        msg = "\0\0\0"+chr(13)+chr(6)+"\0\0\0"+chr(10)+"\0\0\0\0"+"\0\0"+chr(4)+"\0"
        time.sleep(20)
        s.send(msg)
        while 1:
            data = s.recv(4096)
            if not data:
                break
            print "recv {0} :\t\t {1}:{2} ".format(len(data),ip,port),
            for c in data:
                if not c in string.letters:
                    print "{0}".format(ord(c)),
                else:
                    print c,
            print ""
            responses.append(data)
        
        print "disconnect:\t\t {0}:{1} ".format(ip,port) 
        
    def getResponses(self):
        return self.responses

def toBin(x):
    n = x
    ret = ""
    while not n==0:
        for i in range(8):
            if(n & 1):
                ret = "1" + ret
            else:
                ret = "0" + ret
            n = n >>1;
    return ret;

def toDec(x):
	return int(x,2)

def toIP(x): #from large decimal to dotted decimal ip
	b = 256**3
	ret = ""
	for i in range(4):
		#print x
		if(x/b):
			ret = ret+`int(x/b)`+".";
			x = x - x/b*b
		else:
			ret = ret + "0."
		b = b/256;
	return ret[0:-1]


f = open("probe",'rb')
data = f.read();
data = data[data.rfind(":peers60:"):]
data = data[9:]

list = []
a = []
for i in range(len(data)):
    a.append(ord(data[i]))
    if (i+1)%6 ==0:
        list.append(a)
        a = []

ips = []
ports = []
for i in list:
    if len(i) != 6:
        continue
    b = ""
    while not len(i) == 2:
        b = b + toBin(i.pop(0))
    print toIP(toDec(b)) + " :", 
    ips.append(toIP(toDec(b)))
    b = toBin(i.pop(0)) + toBin(i.pop(0)) 
    print toDec(b)
    ports.append(toDec(b))


threads = []
for i in range(len(ips)):
    t = Test(ips[i],ports[i]);
    threads.append(t)
    t.start();

#the following is for catching the signal Ctrl+C from the terminal and actually terminating all threads
while 1:
    try:
        for t in threads:
            t.join(.01)
    except KeyboardInterrupt:
        sys.exit(1)
    


